package com.stwitinc.redmine.dao.news;

import java.sql.SQLException;
import java.sql.Types;
import java.util.Date;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.stwitinc.DateFormat;
import com.stwitinc.data.DbOperator;
import com.stwitinc.data.QueryBuilder;
import com.stwitinc.data.QueryExecutor;
import com.stwitinc.data.model.stwnews.News;
import com.stwitinc.redmine.dao.DAO;
import com.stwitinc.redmine.dao.NewsDAO;

public class NewsDAOImpl  extends DAO implements NewsDAO
{
	@Override
	public int addNews(News rec, long userId) throws SQLException {
		String now = DateFormat.DATE_TIME.getCurrentDate();
		rec.setState("1");
		rec.setCreateTime(now);
		rec.setCreateUserId(String.valueOf(userId));
		rec.setClickCount("0");
		return rec.insert(this);
	}

	@Override
	public int deleteNews(final long newsId, final long userId) throws SQLException {
		Date now = new Date();
		String sql = "update news set state = 3,delete_time = ?,delete_user_id = ? where news_id = ?";
		return executeUpdate(new QueryBuilder(sql)
				.addParameter(Types.TIMESTAMP, now)
				.addParameter(Types.BIGINT, userId)
				.addParameter(Types.BIGINT, newsId));
	}

	@Override
	public JSONObject getNewsById(final long newsId) throws SQLException {
		News rec = new News();
		rec.setNewsId(String.valueOf(newsId));
		return rec.selectFirst(this);
	}

	@Override
	public JSONObject getNewsList(final int state, final int pageIndex) throws SQLException {
		return executeQuery(new QueryExecutor<JSONObject>() {

			@Override
			public JSONObject execute(DbOperator dbo) throws SQLException {
				JSONObject result = new JSONObject();
				String whereClause = " where state = ?";
				String orderByClause;
				if (state == 1) {
					orderByClause = " order by create_time desc";
				} else if (state == 2) {
					orderByClause = " order by publish_time desc";
				} else if (state == 3) {
					orderByClause = " order by delete_time desc";
				} else {
					orderByClause = "";
				}
				int countPerPage = 20;
				int beginIndex = countPerPage * pageIndex;
				String limitClause = " limit " + beginIndex + "," + countPerPage;
				String sql = "select count(1) from news" + whereClause;
				long count = (Long) dbo.executeScalar(new QueryBuilder(sql).addParameter(Types.INTEGER, state));
				int pageCount = (int) count / countPerPage;
				if (count % countPerPage > 0) {
					pageCount++;
				}
				result.put("pageCount", pageCount);
				result.put("pageIndex", pageIndex);
				sql = readSQL("QueryNewsList.sql") + whereClause + orderByClause + limitClause;
				JSONObject data = dbo.executeQuery(new QueryBuilder(sql).addParameter(Types.INTEGER, state));
				JSONArray array = data.getJSONArray("records");
				result.put("records", array);
				return result;
			}
		});
	}

	@Override
	public JSONObject getPublishedNewsById(final long newsId) throws SQLException {
		return executeQuery(new QueryExecutor<JSONObject>() {

			@Override
			public JSONObject execute(DbOperator dbo) throws SQLException {
				News rec = new News();
				rec.setNewsId(String.valueOf(newsId));
				rec.setState("2");
				JSONObject obj = rec.selectFirst(dbo);
				if (obj == null) {
					return null;
				}
				String sql = "update news set click_count = 1 where news_id = ? and click_count is null";
				if (dbo.executeUpdate(new QueryBuilder(sql).addParameter(Types.BIGINT, newsId)) == 0) {
					sql = "update news set click_count = click_count + 1 where news_id = ?";
					dbo.executeUpdate(new QueryBuilder(sql).addParameter(Types.BIGINT, newsId));
				}
				return obj;
			}
		});
	}

	@Override
	public JSONObject getPublishedNewsList(final int pageIndex, final Integer category) throws SQLException {
		JSONObject result = new JSONObject();
		String whereClause = " where state = 2 and category in (0" + (category == null ? "" : "," + category + "") + ")";
		String orderByClause = " order by publish_time desc";
		int countPerPage = 20;
		int beginIndex = countPerPage * pageIndex;
		String limitClause = " limit " + beginIndex + "," + countPerPage;
		String sql = "select count(1) from news" + whereClause;
		long count = (Long) executeScalar(sql);
		int pageCount = (int) count / countPerPage + 1;
		result.put("pageCount", pageCount);
		result.put("pageIndex", pageIndex);
		sql = readSQL("QueryNewsList.sql") + whereClause + orderByClause + limitClause;
		JSONObject data = executeQuery(sql);
		return data;
	}

	@Override
	public int modifyNews(News rec, long userId) throws SQLException {
		Date now = new Date();
		String sql = "update news set modify_time = ?,modify_user_id = ?,category = ?,author_name = ?,title = ?,title_image_uri = ?,content = ? where news_id = ?";
		return executeUpdate(new QueryBuilder(sql)
				.addParameter(Types.TIMESTAMP, now)
				.addParameter(Types.BIGINT, userId)
				.addParameter(Types.INTEGER, rec.getCategory())
				.addParameter(Types.VARCHAR, rec.getAuthorName())
				.addParameter(Types.VARCHAR, rec.getTitle())
				.addParameter(Types.VARCHAR, rec.getTitleImageUri())
				.addParameter(Types.LONGVARCHAR, rec.getContent())
				.addParameter(Types.BIGINT, rec.getNewsId()));
	}

	@Override
	public int publishNews(final long newsId, final long userId) throws SQLException {
		Date now = new Date();
		String sql = "update news set state = 2,publish_time = ?,publish_user_id = ? where news_id = ?";
		return executeUpdate(new QueryBuilder(sql)
				.addParameter(Types.TIMESTAMP, now)
				.addParameter(Types.BIGINT, userId)
				.addParameter(Types.BIGINT, newsId));
	}

}
